#include "include/puts.h"
#include "include/proc.h"

static PROCMSG *proc_msg;
static unsigned int EIP_0;

int get_procnum();
void set_procmsg(PROCSTACK *proc_stack, int *REGS, int *SEGS, unsigned int running, unsigned int last_proc, unsigned int next_proc);

//TEST CODE

static unsigned char c1 = 0;
static unsigned char c2 = 0xFF;

void proc_test1()
{
	for(;;)
	{
		__asm__ __volatile__("cli");

		puts_ex(2, 0, "proc test1 run: ");
		putc_ex(2, 16, c1++);

		__asm__ __volatile__("sti");
	}
}

void proc_test2()
{
	for(;;)
	{
		__asm__ __volatile__("cli");

		puts_ex(3, 0, "proc test2 run: ");
		putc_ex(3, 16, c2++);

		__asm__ __volatile__("sti");
	}
}

void proc_test3()
{
	for(;;)
	{
		__asm__ __volatile__("cli");

		puts_ex(4, 0, "proc test3 run: ");
		putc_ex(4, 16, c1);

		__asm__ __volatile__("sti");
	}
}

void proc_test4()
{
	for(;;)
	{
		__asm__ __volatile__("cli");

		puts_ex(5, 0, "proc test4 run: ");
		putc_ex(5, 16, c2);

		__asm__ __volatile__("sti");
	}
}

void proc_install(const void *addr, const unsigned int eip_0)
{
	// 初始化进程信息地址
	unsigned int REGS[11] = {0};
	unsigned int SEGS[4] = {0};
	//int i;


	proc_msg = (PROCMSG *)addr;
	EIP_0 = eip_0;

	set_procmsg(&(proc_msg -> proc_member[0]), REGS, SEGS, 1, 0, 0);

	// TEST CODE
	create_proc(proc_test1);
	create_proc(proc_test2);
	create_proc(proc_test3);
	create_proc(proc_test4);
}

int proc_run()
{
	// TEST CODE
	//puti_ex(3, 0, (int)(proc_msg -> proc_member[1].reg_msg.EIP));
	//puti_ex(4, 0, (int)&(proc_msg -> proc_member[1].reg_msg.EIP));
	
	return 0;
}

void set_procmsg(PROCSTACK *proc_stack, int *REGS, int *SEGS, unsigned int running, unsigned int last_proc, unsigned int next_proc)
{
	// 设置进程成员信息
	int i;

	for(i = 0; i < 11; i++)
	{
		*(&(proc_stack -> reg_msg.EDI) + i) = REGS[i];
	}

	for(i = 0; i < 4; i++)
	{
		*(&(proc_stack -> data_bp) + i) = SEGS[i];
	}

	proc_stack -> running = running;
	proc_stack -> last_proc = last_proc;
	proc_stack -> next_proc = next_proc;
}

int create_proc(void *func_addr)
{
	// 创建进程;
	int proc_number;
	unsigned int proc_now;
	unsigned int proc_next;
	unsigned int REGS[11] = {0};
	unsigned int SEGS[4] = {0};
	
	if(-1 == (proc_number = get_procnum()))
	{
		return -1;
	}

	proc_now = proc_msg -> proc_now;
	proc_next = proc_msg -> proc_member[proc_now].next_proc;

	proc_msg -> proc_member[proc_now].next_proc = proc_number;
	proc_msg -> proc_member[proc_next].last_proc = proc_number;

	REGS[8] = (int)func_addr + EIP_0;

	set_procmsg(&(proc_msg -> proc_member[proc_number]), REGS, SEGS, 1, proc_now, proc_next);

	return 0;
}

int get_procnum()
{
	int i;

	for(i = 0; i < 64; i++)
	{
		if(0 == proc_msg -> proc_member[i].running)
		{
			proc_msg -> proc_member[i].running = 1;
			return i;
		}
	}

	return -1;
}

